package cfs.controller;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.mybeans.dao.DAOException;
import org.mybeans.form.FormBeanException;
import org.mybeans.form.FormBeanFactory;

import cfs.databean.CFSTransaction;
import cfs.databean.Customer;
import cfs.databean.Fund;
import cfs.databean.FundPriceHistory;
import cfs.formbean.RequestCheckForm;
import cfs.formbean.TransactionForm;
import cfs.helper.Helper;
import cfs.helper.TransactionTypes;
import cfs.model.CustomerDAO;
import cfs.model.FundDAO;
import cfs.model.FundPriceHistoryDAO;
import cfs.model.Model;
import cfs.model.TransactionDAO;

public class RequestCheckAction extends Action {
	private FormBeanFactory<RequestCheckForm> formBeanFactory = FormBeanFactory
			.getInstance(RequestCheckForm.class);

	private TransactionDAO transactionDAO;
	private CustomerDAO customerDAO;
	private FundDAO fundDAO;
	private FundPriceHistoryDAO fundPriceDAO;

	public RequestCheckAction(Model model) {
		transactionDAO = model.getTransactionDao();
		customerDAO = model.getCustomerDao();
		fundDAO = model.getFundDao();
		fundPriceDAO = model.getFundHistoryDao();

	}

	public String getName() {
		return "requestcheck.do";
	}

	public String perform(HttpServletRequest request) {
		List<String> errors = new ArrayList<String>();
		request.setAttribute("errors", errors);

		try {
			//set form attribute
			RequestCheckForm formRequest = formBeanFactory.create(request);
			request.setAttribute("form", formRequest);
			
			//get session user
			Customer user = (Customer) request.getSession()
					.getAttribute("user");

			//set total balance attribute
			long availableBalance = customerDAO.getAvailableBalance(user
					.getCustomer_id());
			request.setAttribute("totalBalance",
					"$" + Helper.longToDouble2String(availableBalance));

			// Fetching all the transactions for the user;
			CFSTransaction[] cfsTransactionList = transactionDAO
					.getTransactions(user.getCustomer_id());
			if (cfsTransactionList != null && cfsTransactionList.length > 0) {
				request.setAttribute("TransactionList", cfsTransactionList);
			}
			
			//first request
			if (!formRequest.isPresent()) {
				return "RequestCheck.jsp";
			}

			//form validation
			errors.addAll(formRequest.getValidationErrors());
			if (errors.size() > 0)
				return "RequestCheck.jsp";

			double amount = Double.parseDouble(String.valueOf(formRequest.getRequestedAmount()));
			long checkAmount = Helper.double2ToLong(amount);
			if (Helper.double2ToLong(amount) > availableBalance) {
				errors.add("The requested amount should be less than Available Balance");
			}

			if (errors.size() > 0)
				return "RequestCheck.jsp";

			// create the request check transaction
			CFSTransaction transaction = new CFSTransaction();
			transaction.setAmount(checkAmount);
			transaction.setCustomer_id(user.getCustomer_id());
			transaction.setTransaction_type(TransactionTypes.REQUEST_CHECK);

			transaction.setRequest_date(new Date((new java.util.Date().getTime())));
			transaction.setStatus(Helper.PENDING_STATUS);
			transaction = transactionDAO.create(transaction);

			// Updating the customer table with the actual available balance
			customerDAO.updateAvailableBalance(user.getCustomer_id(),
					(availableBalance - checkAmount));

			availableBalance = customerDAO.getAvailableBalance(user
					.getCustomer_id());

			request.setAttribute("totalBalance",
					"$" + Helper.longToDouble2String(availableBalance));

			request.setAttribute("msg",
					"Transaction has been successfully added to the queue");

			List<CFSTransaction> transList = transactionDAO.getTransactionList(
					user.getCustomer_id(), TransactionTypes.REQUEST_CHECK);
			List<TransactionForm> formList = new ArrayList<TransactionForm>();
			for (CFSTransaction tran : transList) {
				if (tran.getFund_id() > 0) {
					Fund fund = fundDAO.lookup(tran.getFund_id());
					FundPriceHistory fundPrice;
					TransactionForm form;
					if (tran.getExecute_date() != null) {
						fundPrice = fundPriceDAO.lookup(fund.getFund_id(),
								tran.getExecute_date());
						form = new TransactionForm(tran, fund,
								fundPrice.getPrice());
					} else {
						form = new TransactionForm(tran, fund);
					}

					formList.add(form);
				} else {
					TransactionForm form = new TransactionForm(tran);
					formList.add(form);
				}
			}
			request.setAttribute("formList", formList);
			request.removeAttribute("form");
//			return "RequestCheck.jsp";
			return "customerTransaction.do";
		} catch (DAOException e) {
			errors.add(e.getMessage());
			return "RequestCheck.jsp";
		} catch (FormBeanException e) {
			errors.add(e.getMessage());
			return "RequestCheck.jsp";
		}
	}

}
